﻿using CK.Sprite.Cache;
using CK.Sprite.Framework;
using JetBrains.Annotations;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace CK.Sprite.Form.Core
{
    public class DictService : DomainService
    {
        protected DictDbFrameworkCache DictDbFrameworkCache => LazyGetRequiredService(ref _dictDbFrameworkCache);
        private DictDbFrameworkCache _dictDbFrameworkCache;

        public ICacheSendNotice CacheSendNotice => LazyGetRequiredService(ref _cacheSendNotice);
        private ICacheSendNotice _cacheSendNotice;

        public async Task AddDict(CreateDictDto dictDto)
        {
            var dict = Mapper.Map<CreateDictDto, Dict>(dictDto);
            dict.Id = Guid.NewGuid();

            await _serviceProvider.DoDapperServiceAsync(DefaultDbConfig, async (unitOfWork) =>
            {
                var dictRepository = new GuidRepositoryBase<Dict>(unitOfWork);
                await dictRepository.InsertAsync(dict);

                await ChangeCacheAsync(unitOfWork);
            });
        }

        public async Task UpdateDict(DictDto dictDto)
        {
            await _serviceProvider.DoDapperServiceAsync(DefaultDbConfig, async (unitOfWork) =>
            {
                var dictRepository = new GuidRepositoryBase<Dict>(unitOfWork);
                var dict = await dictRepository.GetAsync(dictDto.Id);
                if (dict == null)
                {
                    throw new SpriteException("未找到Dict数据信息");
                }
                Mapper.Map(dictDto, dict);
                await dictRepository.UpdateAsync(dict);

                await ChangeCacheAsync(unitOfWork);
            });
        }

        public async Task DeleteDict(Guid id)
        {
            await _serviceProvider.DoDapperServiceAsync(DefaultDbConfig, async (unitOfWork) =>
            {
                var dictRepository = new GuidRepositoryBase<Dict>(unitOfWork);
                var dictItemRepository = ConnectionFactory.GetConnectionProvider(DefaultDbConfig.ConnectionType).GetRepository<IDictItemRepository>(unitOfWork);
                var deleteData = await dictRepository.GetAsync(id);
                if (deleteData == null)
                {
                    throw new SpriteException("未找到Dict数据信息");
                }
                await dictItemRepository.DeleteDictItemsByDictCode(deleteData.Code);
                await dictRepository.DeleteAsync(deleteData);
                await ChangeCacheAsync(unitOfWork);
            });
        }

        public async Task AddDictItem(CreateDictItemDto dictItemDto)
        {
            var dictItem = Mapper.Map<CreateDictItemDto, DictItem>(dictItemDto);
            dictItem.Id = Guid.NewGuid();

            await _serviceProvider.DoDapperServiceAsync(DefaultDbConfig, async (unitOfWork) =>
            {
                var dictItemRepository = new GuidRepositoryBase<DictItem>(unitOfWork);
                await dictItemRepository.InsertAsync(dictItem);

                await ChangeCacheAsync(unitOfWork);
            });
        }

        public async Task UpdateDictItem(DictItemDto dictItemDto)
        {
            await _serviceProvider.DoDapperServiceAsync(DefaultDbConfig, async (unitOfWork) =>
            {
                var dictItemRepository = new GuidRepositoryBase<DictItem>(unitOfWork);
                var dictItem = await dictItemRepository.GetAsync(dictItemDto.Id);
                if (dictItem == null)
                {
                    throw new SpriteException("未找到DictItem数据信息");
                }
                Mapper.Map(dictItemDto, dictItem);
                await dictItemRepository.UpdateAsync(dictItem);

                await ChangeCacheAsync(unitOfWork);
            });
        }

        public async Task DeleteDictItem(Guid id)
        {
            await _serviceProvider.DoDapperServiceAsync(DefaultDbConfig, async (unitOfWork) =>
            {
                var dictItemRepository = new GuidRepositoryBase<DictItem>(unitOfWork);
                var deleteData = await dictItemRepository.GetAsync(id);
                if (deleteData == null)
                {
                    throw new SpriteException("未找到DictItem数据信息");
                }
                await dictItemRepository.DeleteAsync(deleteData);

                await ChangeCacheAsync(unitOfWork);
            });
        }

        public async Task<List<DictDto>> GetDictList()
        {
            var dicts = await _serviceProvider.DoDapperServiceAsync(DefaultDbConfig, async (unitOfWork) =>
            {
                var dictRepository = new GuidRepositoryBase<Dict>(unitOfWork);
                var dbDicts = await dictRepository.GetAllAsync();
                return dbDicts.ToList();
            });

            return Mapper.Map<List<Dict>, List<DictDto>>(dicts.OrderBy(r=>r.Code).ToList());
        }

        public async Task<List<DictItemDto>> GetDictItemList(string dictCode)
        {
            var dicts = await _serviceProvider.DoDapperServiceAsync(DefaultDbConfig, async (unitOfWork) =>
            {
                var dictItemRepository = ConnectionFactory.GetConnectionProvider(DefaultDbConfig.ConnectionType).GetRepository<IDictItemRepository>(unitOfWork);
                var dbDictItems = await dictItemRepository.GetDictItemsByDictCode(dictCode);
                return dbDictItems.ToList();
            });

            return Mapper.Map<List<DictItem>, List<DictItemDto>>(dicts.OrderBy(r=>r.Order).ToList());
        }

        private async Task ChangeCacheAsync(IUnitOfWork unitOfWork)
        {
            var spriteCacheMainRepository = new RepositoryBase<SpriteCacheMain, string>(unitOfWork);
            var spriteCacheMain = await spriteCacheMainRepository.GetAsync(CommonConsts.FrameworkDictCacheKey);
            spriteCacheMain.Version = Guid.NewGuid().ToString();
            await spriteCacheMainRepository.UpdateAsync(spriteCacheMain);

            CacheSendNotice.SendClearCache($"{CommonConsts.SpriteFormCachePreKey}-CacheMain_{CommonConsts.FrameworkDictCacheKey}");
            CacheSendNotice.SendClearCache($"{CommonConsts.SpriteFormCachePreKey}-{CommonConsts.FrameworkDictCacheKey}");
        }
    }
}
